﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using CommonLibrary;
using Newtonsoft.Json;

namespace 任务状态
{
    public class CandleStickChart
    {
        private readonly int width;
        private readonly int height;
        private DailyDataWithStyle[] weeklyData = new DailyDataWithStyle[5];
        private ConfigManager configManager;
        private const int CandleWidth = 7;
        private const int CandleSpacing = 2;

        public CandleStickChart(int width, int height)
        {
            this.width = width;
            this.height = height;
            configManager = new ConfigManager("AppConfigs");
            LoadCompleteSettings();
        }

        /// <summary>
        /// 保存完整配置（每个交易日的数据和独立颜色）
        /// </summary>
        public void SaveCompleteSettings()
        {
            try
            {
                var saveData = new CompleteChartSettings
                {
                    WeeklyData = weeklyData,
                    LastSaveTime = DateTime.Now
                };

                configManager.SaveConfig(saveData, "chart_complete_settings.json");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"保存完整配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 加载完整配置
        /// </summary>
        private void LoadCompleteSettings()
        {
            try
            {
                var loadedData = configManager.LoadConfig<CompleteChartSettings>("chart_complete_settings.json");
                if (loadedData != null && loadedData.WeeklyData != null)
                {
                    weeklyData = loadedData.WeeklyData;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"加载完整配置失败: {ex.Message}");
                weeklyData = new DailyDataWithStyle[5];
            }
        }

        /// <summary>
        /// 设置全局颜色模板（应用于所有交易日）
        /// </summary>
        public void SetGlobalColors(Color upColor, Color downColor, Color borderColor)
        {
            for (int i = 0; i < weeklyData.Length; i++)
            {
                if (weeklyData[i] != null)
                {
                    weeklyData[i].UpColor = ColorToInt(upColor);
                    weeklyData[i].DownColor = ColorToInt(downColor);
                    weeklyData[i].BorderColor = ColorToInt(borderColor);
                }
            }
            SaveCompleteSettings();
        }

        /// <summary>
        /// 为特定交易日设置独立颜色
        /// </summary>
        public void SetDailyColors(DayOfWeek dayOfWeek, Color upColor, Color downColor, Color borderColor)
        {
            int index = (int)dayOfWeek - (int)DayOfWeek.Monday;
            if (index >= 0 && index < weeklyData.Length && weeklyData[index] != null)
            {
                weeklyData[index].UpColor = ColorToInt(upColor);
                weeklyData[index].DownColor = ColorToInt(downColor);
                weeklyData[index].BorderColor = ColorToInt(borderColor);
                SaveCompleteSettings();
            }
        }

        public void AddDailyData(DateTime date, float open, float high, float low, float close,
                               Color? upColor = null, Color? downColor = null, Color? borderColor = null)
        {
            if (date.DayOfWeek < DayOfWeek.Monday || date.DayOfWeek > DayOfWeek.Friday)
                return;

            // 新的一周清除数据
            if (weeklyData.Any(d => d != null && d.Date.Date.AddDays(7) <= date.Date))
            {
                Array.Clear(weeklyData, 0, weeklyData.Length);
            }

            int index = (int)date.DayOfWeek - (int)DayOfWeek.Monday;

            // 使用提供的颜色或默认颜色
            Color finalUpColor = upColor ?? (close >= open ? Color.Red : Color.Green);
            Color finalDownColor = downColor ?? (close >= open ? Color.Red : Color.Green);
            Color finalBorderColor = borderColor ?? Color.Black;

            weeklyData[index] = new DailyDataWithStyle
            {
                Date = date,
                Open = open,
                High = high,
                Low = low,
                Close = close,
                UpColor = ColorToInt(finalUpColor),
                DownColor = ColorToInt(finalDownColor),
                BorderColor = ColorToInt(finalBorderColor)
            };

            SaveCompleteSettings();
        }

        /// <summary>
        /// 获取交易日的数据和颜色
        /// </summary>
        public DailyDataWithStyle GetDailyData(DayOfWeek dayOfWeek)
        {
            int index = (int)dayOfWeek - (int)DayOfWeek.Monday;
            return index >= 0 && index < weeklyData.Length ? weeklyData[index] : null;
        }

        // 颜色转换方法
        private int ColorToInt(Color color) => color.ToArgb();
        private Color IntToColor(int argb) => Color.FromArgb(argb);

        public Bitmap DrawToBitmap()
        {
            Bitmap bmp = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.Transparent);

                var validData = weeklyData.Where(d => d != null).ToArray();
                if (validData.Length == 0)
                    return bmp;

                float minPrice = validData.Min(d => d.Low);
                float maxPrice = validData.Max(d => d.High);

                for (int i = 0; i < weeklyData.Length; i++)
                {
                    if (weeklyData[i] == null)
                        continue;

                    var data = weeklyData[i];
                    int x = i * (CandleWidth + CandleSpacing);

                    int highY = PriceToY(data.High, minPrice, maxPrice);
                    int lowY = PriceToY(data.Low, minPrice, maxPrice);
                    int openY = PriceToY(data.Open, minPrice, maxPrice);
                    int closeY = PriceToY(data.Close, minPrice, maxPrice);

                    bool isUp = data.Close >= data.Open;
                    Color color = isUp ? IntToColor(data.UpColor) : IntToColor(data.DownColor);
                    Color borderColor = IntToColor(data.BorderColor);

                    using (Pen pen = new Pen(borderColor, 1))
                    {
                        g.DrawLine(pen, x + CandleWidth / 2, highY, x + CandleWidth / 2, lowY);
                    }

                    int bodyTop = Math.Min(openY, closeY);
                    int bodyHeight = Math.Max(1, Math.Abs(openY - closeY));
                    using (Brush brush = new SolidBrush(color))
                    {
                        g.FillRectangle(brush, x, bodyTop, CandleWidth, bodyHeight);
                    }
                }
            }
            return bmp;
        }

        private int PriceToY(float price, float minPrice, float maxPrice)
        {
            float priceRange = maxPrice - minPrice;
            if (priceRange == 0) return height / 2;
            float ratio = (price - minPrice) / priceRange;
            return 1 + (int)((1 - ratio) * (height - 3));
        }
    }

    /// <summary>
    /// 带样式的日数据类（数据 + 颜色）
    /// </summary>
    [Serializable]
    public class DailyDataWithStyle
    {
        public DateTime Date { get; set; }
        public float Open { get; set; }
        public float High { get; set; }
        public float Low { get; set; }
        public float Close { get; set; }
        public int UpColor { get; set; } = Color.Red.ToArgb();
        public int DownColor { get; set; } = Color.Green.ToArgb();
        public int BorderColor { get; set; } = Color.Black.ToArgb();
    }

    /// <summary>
    /// 完整图表设置
    /// </summary>
    [Serializable]
    public class CompleteChartSettings
    {
        public DailyDataWithStyle[] WeeklyData { get; set; }
        public DateTime LastSaveTime { get; set; }
    }
}